package com.loooooo.pm2024.modules.pm.service;


import com.loooooo.pm2024.exception.MyBaseException;
import com.loooooo.pm2024.modules.pm.mapper.WorkLogMapper;
import com.loooooo.pm2024.modules.pm.mapper.WorkLogMapper;
import com.loooooo.pm2024.modules.pm.model.Attachment;
import com.loooooo.pm2024.modules.pm.model.Task;
import com.loooooo.pm2024.modules.pm.model.WorkLog;
import com.loooooo.pm2024.modules.pm.model.WorkSummary;
import com.loooooo.pm2024.modules.pm.selector.AttachmentSelector;
import com.loooooo.pm2024.modules.pm.selector.WorkLogSelector;
import com.loooooo.pm2024.modules.pm.selector.WorkSummarySelector;
import com.loooooo.pm2024.security.SecurityUtils;
import com.loooooo.pm2024.service.IdService;
import com.loooooo.pm2024.utils.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;
import org.springframework.util.StringUtils;

import java.time.LocalDate;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
public class WorkLogService {

    @Autowired
    WorkLogMapper workLogMapper;
    @Autowired
    IdService idService;
    @Autowired
    TaskService taskService;

    @Autowired
    IssueService issueService;
    @Autowired
    TransactionTemplate transactionTemplate;

    public WorkLog get(Long id) {
        return get(id, null);
    }


    public WorkLog get(Long id, WorkLogSelector selector) {
        WorkLog comment = workLogMapper.get(id);
        if (selector != null && comment != null) {

        }
        return comment;
    }

    public List<WorkLog> list(WorkLogSelector selector) {
        if (Objects.equals(1, selector.getMine())) {
            selector.getTarget().setOwnerId(SecurityUtils.loginedUserId());
        }
        List<WorkLog> list = workLogMapper.select(selector);
        if (list.size() > 0) {

        }
        return list;
    }

    public int count(WorkLogSelector selector) {
        if (Objects.equals(1, selector.getMine())) {
            selector.getTarget().setOwnerId(SecurityUtils.loginedUserId());
        }
        return workLogMapper.count(selector);
    }

    public int update(WorkLog workLog) {
        long now = System.currentTimeMillis();
        workLog.setUpdatedAt(now);
        Long userId = SecurityUtils.loginedUserId();
        workLog.setUpdatedBy(userId);

        if (workLog.getId() == null || workLog.isNewEntity() || workLog.getId() <= 0L) {
            if (userId == null) {
                MyBaseException.throwMe(10401, "未登录");
            }
            if (workLog.getId() == null || workLog.getId() <= 0L) {
                workLog.setId(idService.nextId());
            }
            if (workLog.getBusinessDate() == null) {
                workLog.setBusinessDate(DateUtils.localDate2Long(LocalDate.now()));

            }
            if (!StringUtils.hasText(workLog.getSubject())) {

            }
            workLog.setOwnerId(userId);
            if (workLog.getTaskId() != null) {
                Task task = taskService.get(workLog.getTaskId());
                if (task == null) {
                    MyBaseException.throwMe(10404, "关联任务不存在。");
                }
                workLog.setType("task");
                workLog.setTaskId(task.getId());
                workLog.setIssueId(task.getIssueId());
                if (!StringUtils.hasText(workLog.getSubject())) {
                    workLog.setSubject(task.getSubject());
                }
                if (!Objects.equals(userId, task.getOwnerId())) {
                    MyBaseException.throwMe(10404, "你不是关联到的任务所有者。");
                }
            }
            if (!StringUtils.hasText(workLog.getSubject())) {
                //MyBaseException.throwMe(10404, "关联任务不存在。");
            }
            workLog.setCreatedAt(now);
            workLog.setCreatedBy(userId);
            int r = transactionTemplate.execute(new TransactionCallback<Integer>() {
                @Override
                public Integer doInTransaction(TransactionStatus status) {
                    int r = workLogMapper.insert(workLog);
                    if (r > 0 && workLog.getTaskId() != null && workLog.getDuration() != null) {
                        WorkLogSelector selector = new WorkLogSelector();
                        selector.getTarget().setTaskId(workLog.getTaskId());
                        List<WorkLog> ls = list(selector);
                        Integer duration = ls.stream().mapToInt(x -> x.getDuration() == null ? 0 : x.getDuration()).sum();
                        Task task = taskService.get(workLog.getTaskId());
                        task.setTime(duration);
                        taskService.update(task);
                    }
                    return r;
                }
            });
            return r;

        }
        WorkLog log0 = get(workLog.getId());
        if (!Objects.equals(log0.getOwnerId(), userId)) {
            MyBaseException.throwMe(10403, "请勿修改他人工时记录。");
        }

        int r = transactionTemplate.execute(new TransactionCallback<Integer>() {
            @Override
            public Integer doInTransaction(TransactionStatus status) {
                int r = workLogMapper.update(workLog);
                if (r > 0 && workLog.getTaskId() != null && workLog.getDuration() != null) {
                    WorkLogSelector selector = new WorkLogSelector();
                    selector.getTarget().setTaskId(workLog.getTaskId());
                    List<WorkLog> ls = list(selector);
                    Integer duration = ls.stream().mapToInt(x -> x.getDuration() == null ? 0 : x.getDuration()).sum();
                    Task task = taskService.get(workLog.getTaskId());
                    task.setTime(duration);
                    taskService.update(task);
                }
                return r;
            }
        });
        return r;
    }

    public List<WorkSummary> summaries(WorkSummarySelector selector) {
        if (selector == null) {
            selector = new WorkSummarySelector();
        }
        if (Objects.equals(1, selector.getMine())) {
            selector.getTarget().setId(SecurityUtils.loginedUserId());
        }
        LocalDate today = LocalDate.now();
        LocalDate firstDay = LocalDate.of(today.getYear(), today.getMonth(), 1);

        selector.setBusinessAfter1(DateUtils.localDate2Long(firstDay));
        selector.setBusinessBefore1(System.currentTimeMillis());

        LocalDate firstDay2 = firstDay.plusMonths(-1);
        selector.setBusinessAfter2(DateUtils.localDate2Long(firstDay2));
        selector.setBusinessBefore2(DateUtils.localDate2Long(firstDay) - 1);
        return workLogMapper.summary(selector);
    }

    public WorkSummary summaries(Long userId) {
        WorkSummarySelector selector = new WorkSummarySelector();
        selector.getTarget().setId(userId);
        LocalDate today = LocalDate.now();
        LocalDate firstDay = LocalDate.of(today.getYear(), today.getMonth(), 1);

        selector.setBusinessAfter1(DateUtils.localDate2Long(firstDay));
        selector.setBusinessBefore1(System.currentTimeMillis());

        LocalDate firstDay2 = firstDay.plusMonths(-1);
        selector.setBusinessAfter2(DateUtils.localDate2Long(firstDay2));
        selector.setBusinessBefore2(DateUtils.localDate2Long(firstDay) - 1);
        return workLogMapper.summary(selector).stream().findAny().orElse(null);
    }

    public WorkSummary mySummaries() {
        return summaries(SecurityUtils.loginedUserId());
    }

}
